# -*- coding: utf-8 -*-
import json
import random
from urllib.parse import quote
import time
from datetime import datetime, timedelta
import os
from typing import List, Optional, Union
from faker import Faker

class CommonUtils:
    """通用工具类，提供各种辅助功能"""
    fake = Faker('zh_CN')

    @staticmethod
    def generate_phone_number() -> str:
        """
        生成随机的11位手机号码（默认199开头）

        Returns:
            str: 随机生成的11位手机号码，格式：199xxxxxxxx
        """
        # 前三位固定为199，后8位随机生成
        return '199' + ''.join(random.choices('0123456789', k=8))


    @staticmethod
    def generate_random_chinese_text(num_sentences: int = 3) -> str:
        """
        生成随机的中文文案
        
        Args:
            num_sentences: 生成的句子数量，默认3句
        
        Returns:
            str: 随机生成的中文文案
        """
        text = []
        for _ in range(num_sentences):
            text.append(CommonUtils.fake.sentence())
        return ' '.join(text)

    @staticmethod
    def url_encode(text: str) -> str:
        """
        对传入的字符串进行 URL 编码，并返回编码后的结果
        
        Args:
            text: 需要进行编码的字符串
        
        Returns:
            str: 编码后的字符串
        
        Example:
            >>> CommonUtils.url_encode("你好，世界！")
            '%E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%96%E7%95%8C%EF%BC%81'
        """
        return quote(text, safe='')
    @staticmethod
    def format_response_for_log(response):
        """统一处理响应内容用于日志记录"""
        try:
            resp = json.loads(response.text)
        except json.JSONDecodeError:
            resp = response.text

        if isinstance(resp, (dict, list)):
            formatted = json.dumps(resp, ensure_ascii=False, indent=4)
        else:
            formatted = str(resp)
        return resp, formatted


class TimeUtils:
    """时间工具类，提供时间相关的辅助功能"""
    
    @staticmethod
    def get_timestamp(time_str: Optional[str] = None) -> int:
        """
        将时间字符串转换为时间戳，如果不传入时间则返回当前时间的时间戳
        
        Args:
            time_str: 时间字符串，格式为 '%Y-%m-%d %H:%M:%S'
        
        Returns:
            int: 时间戳
        """
        if time_str is None:
            return int(time.time())
        else:
            return int(time.mktime(time.strptime(time_str, '%Y-%m-%d %H:%M:%S')))

    @staticmethod
    def format_timestamp(timestamp: Optional[Union[int, float]] = None) -> str:
        """
        将时间戳转换为当前时间的字符串表示
        
        Args:
            timestamp: 时间戳，如果不提供则使用当前时间
        
        Returns:
            str: 当前时间的字符串表示
        """
        if timestamp is None:
            return str(datetime.today())
        return datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')

    @staticmethod
    def get_current_timestamp() -> int:
        """
        获取当前时间戳
        
        Returns:
            int: 当前时间的时间戳
        """
        return int(time.time())

    @staticmethod
    def get_current_timestamp_plus_seconds(seconds: int = 10) -> int:
        """
        获取当前时间加上指定秒数的时间戳
        
        Args:
            seconds: 要增加的秒数，默认10秒
        
        Returns:
            int: 增加后的时间戳
        """
        return int(time.time() + seconds)

    @staticmethod
    def get_current_date_with_zero_time() -> str:
        """
        获取当天日期，时分秒均为0
        
        Returns:
            str: 格式化的日期字符串，格式为 '%Y-%m-%d %H:%M:%S'
        """
        date_time = datetime.date.today()
        return datetime.strftime(date_time, "%Y-%m-%d %H:%M:%S")

    @staticmethod
    def get_current_datetime() -> str:
        """
        获取当前的完整时间
        
        Returns:
            str: 格式化的时间字符串，格式为 '%Y-%m-%d %H:%M:%S'
        """
        date_time = datetime.today()
        return datetime.strftime(date_time, "%Y-%m-%d %H:%M:%S")

    @staticmethod
    def get_current_datetime_plus_seconds(seconds: int = 10) -> str:
        """
        获取当前时间加上指定秒数的完整时间
        
        Args:
            seconds: 要增加的秒数，默认10秒
        
        Returns:
            str: 格式化的时间字符串，格式为 '%Y-%m-%d %H:%M:%S'
        """
        date_time = datetime.today() + timedelta(seconds=seconds)
        return datetime.strftime(date_time, "%Y-%m-%d %H:%M:%S")

    @staticmethod
    def get_current_date() -> str:
        """
        获取当前日期，格式为 '%Y-%m-%d'
        
        Returns:
            str: 格式化的日期字符串
        """
        date_time = datetime.today()
        return datetime.strftime(date_time, "%Y-%m-%d")

    @staticmethod
    def generate_date_based_code() -> str:
        """
        生成基于日期的验证码（日期+星期几）
        
        Returns:
            str: 格式为'日星期几'的验证码（例如'2602'表示26号星期二）
        """
        today = datetime.now()
        day_str = today.strftime("%d")  # 获取日的两位数表示
        weekday_index = today.weekday()  # 获取星期几（0代表星期一，6代表星期日）
        weekday_str = str(weekday_index + 1).zfill(2)  # 转换为字符串并补零
        
        return f'{day_str}{weekday_str}'


class SerialNumberGenerator:
    """序列号生成器，提供各种类型的序列号生成功能"""
    fake = Faker('zh_CN')
    
    @staticmethod
    def generate_transaction_serial_no() -> str:
        """
        生成随机交易流水号
        
        Returns:
            str: 以'FZ'开头的交易流水号
        """
        return SerialNumberGenerator.fake.bothify("FZ##################")

    @staticmethod
    def generate_payment_flow_no() -> str:
        """
        生成支付流水号
        
        Returns:
            str: 随机支付流水号
        """
        return SerialNumberGenerator.fake.bothify("####################")

    @staticmethod
    def generate_bank_flow_no() -> str:
        """
        生成银行流水号
        
        Returns:
            str: 随机银行流水号
        """
        return SerialNumberGenerator.fake.bothify("############################")


class TestOrderManager:
    """测试订单管理器，用于控制测试订单的执行次数"""
    COUNT_FILE = 'test_order_module_count.json'
    
    @staticmethod
    def can_execute_test() -> bool:
        """
        判断是否可以执行测试（每天最多执行3次）
        
        Returns:
            bool: 如果可以执行测试返回True，否则返回False
        """
        today = datetime.now().strftime('%Y-%m-%d')
        
        if not os.path.exists(TestOrderManager.COUNT_FILE):
            # 如果文件不存在就初始化文件
            with open(TestOrderManager.COUNT_FILE, 'w') as f:
                json.dump({today: 0}, f)
            return True
        
        with open(TestOrderManager.COUNT_FILE, 'r') as f:
            data = json.load(f)

        if today not in data:
            data = {today: 0}
            with open(TestOrderManager.COUNT_FILE, 'w') as f:
                json.dump(data, f)
            return True
            
        return data[today] < 3

    @staticmethod
    def increment_test_count() -> None:
        """
        增加测试执行次数计数
        """
        today = datetime.now().strftime('%Y-%m-%d')
        
        # 如果文件不存在，先创建
        if not os.path.exists(TestOrderManager.COUNT_FILE):
            with open(TestOrderManager.COUNT_FILE, 'w') as f:
                json.dump({today: 1}, f)
            return
            
        with open(TestOrderManager.COUNT_FILE, 'r') as f:
            data = json.load(f)
            
        data[today] = data.get(today, 0) + 1
        
        with open(TestOrderManager.COUNT_FILE, 'w') as f:
            json.dump(data, f)


class ParamUtils:
    """参数处理工具类，提供参数相关的辅助功能"""
    
    @staticmethod
    def get_random_param(params: List) -> Union[str, int, float, bool, dict, list]:
        """
        从参数列表中随机选择一个参数
        
        Args:
            params: 参数列表
        
        Returns:
            随机选择的参数
        """
        return random.sample(params, 1)[0]


if __name__ == '__main__':
    # 示例用法
    print(f"随机手机号: {CommonUtils.generate_phone_number()}")
    print(f"当前时间: {TimeUtils.get_current_datetime()}")
    print(f"交易流水号: {SerialNumberGenerator.generate_transaction_serial_no()}")
    print(f"是否可以执行测试: {TestOrderManager.can_execute_test()}")
